package com.bjy.qa.agent.tester.handler.tester;

import com.alibaba.fastjson.JSONObject;
import com.bjy.qa.agent.enumtype.RunStatus;
import com.bjy.qa.agent.exception.ExceptionUtils;
import com.bjy.qa.agent.exception.MyException;
import com.bjy.qa.agent.model.HandleDes;
import com.bjy.qa.agent.tester.RunStepThread;
import com.bjy.qa.agent.tester.handlers.StepHandlers;
import com.bjy.qa.agent.tools.SpringTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * Tester 测试任务步骤运行线程
 */
public class TesterRunStepThread extends RunStepThread {
    private final Logger logger = LoggerFactory.getLogger(TesterRunStepThread.class);

    public final static String STEP_TASK_PRE = "tester-run-step-task-rid%s-cid%s"; // 占用符逻辑参考

    private final TesterTaskBootThread testerTaskBootThread; // 测试任务启动线程（Tester 启动各个子任务的线程）

    /**
     * 构造函数
     * @param testerTaskBootThread
     */
    public TesterRunStepThread(TesterTaskBootThread testerTaskBootThread) {
        this.testerTaskBootThread = testerTaskBootThread;

        this.setDaemon(true); // 设置为守护线程（当JVM中的所有用户线程结束时,该守护线程也会被自动终止）
        this.setName(testerTaskBootThread.formatThreadName(STEP_TASK_PRE)); // 设置线程名称
        setLogTool(testerTaskBootThread.getTesterStepHandler().getLog()); // 设置上报运行结果工具类
    }

    /**
     * 获取测试任务启动线程（Tester 启动各个子任务的线程）
     * @return
     */
    public TesterTaskBootThread getTesterTaskBootThread() {
        return testerTaskBootThread;
    }

    /**
     * 获取测试步骤处理器
     * @return
     */
    @Override
    public void run() {
        StepHandlers stepHandlers = SpringTool.getBean(StepHandlers.class); // 获取步骤处理器
        JSONObject jsonObject = testerTaskBootThread.getJsonObject(); // 获取测试任务信息
        List<JSONObject> steps = jsonObject.getJSONArray("steps").toJavaList(JSONObject.class); // 获取测试步骤列表

        // 遍历步骤，运行步骤
        HandleDes handleDes = new HandleDes();
        for (JSONObject step : steps) {
            if (isStopped()) {
                return;
            }
            try {
                stepHandlers.runStep(step, handleDes, this);
            } catch (MyException e) { // 业务逻辑抛出的异常会被外层 catch 后抛出，这里无须处理
                break;
            } catch (AssertionError e) { // 断言业务逻辑抛出的异常会被外层 catch 后抛出，这里无须处理
                break;
            } catch (Throwable e) {
                testerTaskBootThread.getTesterStepHandler().logUtil.sendStepLog(RunStatus.ERROR, handleDes.getStepDesc(), handleDes.getStepType(), ExceptionUtils.getStackTrace(e));
                testerTaskBootThread.getTesterStepHandler().logUtil.sendStatusLog(RunStatus.FAILED);
                e.printStackTrace();
                break;
            }
        }
    }
}